package com.springboot.ball.consumer.games;

import com.alibaba.fastjson.JSONObject;
import com.springboot.ball.consumer.WebSocketServer;
import com.springboot.ball.pojo.User;

import java.util.ArrayList;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

import java.util.concurrent.locks.ReentrantLock;

public class Game extends Thread {
    // 游戏参数
    private double playerRadius;  // 玩家半径
    private double playerSpeed;   // 玩家速度
    private double fireballDamage = 20.0;  // 火球伤害

    private final int width;
    private final int height;
    private final Player playerA, playerB, playerC;
    private String status = "playing";  // playing -> finished
    private String loser = "";  // all: 平局，A: A输，B: B输, C: C输, AB: AB输, BC: BC输, AC: AC输

    private ReentrantLock lock = new ReentrantLock();
    private boolean gameOver = false;

    public Game(Integer idA, Integer idB, Integer idC, int width, int height, double playerRadius, double playerSpeed) {
        this.width = width;
        this.height = height;
        this.playerRadius = playerRadius;
        this.playerSpeed = playerSpeed;

        // 计算三角形的三个顶点坐标
        // 假设三角形的边长约为屏幕高度的1/3
        double triangleSize = height / 3.5;

        // 三角形中心位于屏幕中心
        double centerX = width / 2;
        double centerY = height / 2;

        // 三角形顶点坐标
        // A位于三角形顶部
        double playerAX = centerX;
        double playerAY = centerY - triangleSize * 0.866; // 0.866 = √3/2

        // B位于左下角
        double playerBX = centerX - triangleSize / 2;
        double playerBY = centerY + triangleSize * 0.433; // 0.433 = √3/4

        // C位于右下角
        double playerCX = centerX + triangleSize / 2;
        double playerCY = centerY + triangleSize * 0.433;

        System.out.println("初始化三个玩家的位置：");
        System.out.println("玩家A: (" + playerAX + ", " + playerAY + ")");
        System.out.println("玩家B: (" + playerBX + ", " + playerBY + ")");
        System.out.println("玩家C: (" + playerCX + ", " + playerCY + ")");

        // 初始化三个玩家
        this.playerA = new Player(idA, playerAX, playerAY, playerRadius, playerSpeed, false, new ArrayList<>(), 0, 0);
        this.playerB = new Player(idB, playerBX, playerBY, playerRadius, playerSpeed, false, new ArrayList<>(), 0, 0);
        this.playerC = new Player(idC, playerCX, playerCY, playerRadius, playerSpeed, false, new ArrayList<>(), 0, 0);
    }

    public Player getPlayerA() {
        return playerA;
    }

    public Player getPlayerB() {
        return playerB;
    }

    public Player getPlayerC() {
        return playerC;
    }
    // 在Game类中添加状态获取方法
    public String getStatus() {
        return status;
    }

    // 在Game类中添加状态设置方法（可选但推荐）
    public void setStatus(String status) {
        this.status = status;
    }

    // 新增：获取火球伤害值
    public double getFireballDamage() {
        return fireballDamage;
    }
    // 根据ID获取玩家对象
    public Player getPlayerById(Integer playerId) {
        if (playerA.getId().equals(playerId)) return playerA;
        if (playerB.getId().equals(playerId)) return playerB;
        if (playerC.getId().equals(playerId)) return playerC;
        return null;
    }

    // 处理玩家死亡
    public void playerDeath(String playerIdentifier) {
        lock.lock();
        try {
            // 状态检查：仅在游戏进行时处理死亡
            if (!status.equals("playing")) {
                System.out.println("游戏已不在进行中，忽略playerDeath调用, 当前状态: " + status);
                return;
            }
            
            System.out.println("处理玩家死亡: " + playerIdentifier);
            
            // 获取要处理的玩家对象
            Player deadPlayer = getPlayerByIdentifier(playerIdentifier);
            if (deadPlayer == null) {
                System.out.println("无效的玩家标识: " + playerIdentifier);
                return;
            }
            
            int playerId = deadPlayer.getId();
            
            // 检查玩家是否已经死亡
            if (!deadPlayer.isAlive()) {
                System.out.println("玩家" + playerIdentifier + "已经是死亡状态，不再重复处理");
                return;
            }
            
            // 设置死亡状态
            deadPlayer.kill();
            System.out.println("玩家" + playerIdentifier + "死亡");
            
            // 广播死亡事件给所有客户端
            JSONObject deathEvent = new JSONObject();
            deathEvent.put("event", "player_death");
            deathEvent.put("player_id", playerId);
            deathEvent.put("identifier", playerIdentifier);
            sendAllMessage(deathEvent.toJSONString());
            System.out.println("已向所有客户端广播玩家" + playerIdentifier + "(" + playerId + ")的死亡事件");

            // 检查游戏是否结束
            checkGameResult();
        } finally {
            lock.unlock();
        }
    }

    // 通过标识符获取玩家对象
    private Player getPlayerByIdentifier(String identifier) {
        switch (identifier) {
            case "A": return playerA;
            case "B": return playerB;
            case "C": return playerC;
            default: return null;
        }
    }

    // 检查游戏结果
    public void checkGameResult() {
        if (!status.equals("playing")) {
            return;
        }
        
        // 统计存活玩家数量
        int aliveCount = 0;
        Player lastAlivePlayer = null;
        
        System.out.println("检查游戏结束条件");
        
        // 检查所有玩家状态
        for (Player player : new Player[]{playerA, playerB, playerC}) {
            String playerLabel = player == playerA ? "A" : (player == playerB ? "B" : "C");
            System.out.println("玩家" + playerLabel + "状态: " + (player.isAlive() ? "存活" : "死亡"));
            
            if (player.isAlive()) {
                aliveCount++;
                lastAlivePlayer = player;
            }
        }
        
        System.out.println("存活玩家数量: " + aliveCount);

        // 游戏结束条件判断
        if (aliveCount == 0) {
            // 所有玩家死亡，平局
            finishGame("all", null);
        } else if (aliveCount == 1 && lastAlivePlayer != null) {
            // 确定胜利者和失败者
            String winnerIdentifier = lastAlivePlayer == playerA ? "A" : 
                                      (lastAlivePlayer == playerB ? "B" : "C");
            
            // 根据胜利者确定失败者组合
            String loserIdentifier;
            if (winnerIdentifier.equals("A")) {
                loserIdentifier = "BC";
                ensurePlayerDead(playerB);
                ensurePlayerDead(playerC);
            } else if (winnerIdentifier.equals("B")) {
                loserIdentifier = "AC";
                ensurePlayerDead(playerA);
                ensurePlayerDead(playerC);
            } else {
                loserIdentifier = "AB";
                ensurePlayerDead(playerA);
                ensurePlayerDead(playerB);
            }
            
            finishGame(loserIdentifier, winnerIdentifier);
        }
    }

    // 确保玩家处于死亡状态
    private void ensurePlayerDead(Player player) {
        player.kill();
    }

    // 完成游戏，发送结果
    private void finishGame(String loserIdentifier, String winnerIdentifier) {
        status = "finished";
        gameOver = true;
        loser = loserIdentifier;
        
        if (winnerIdentifier != null) {
            System.out.println("游戏结束，" + winnerIdentifier + "胜利");
        } else {
            System.out.println("游戏结束，平局");
        }
        
        sendResult();
    }

    private void sendResult(){
        JSONObject resp = new JSONObject();
        resp.put("event", "result");
        resp.put("loser", loser);
        saveToDatabase();
        sendAllMessage(resp.toJSONString());
    }

    public void sendAllMessage(String message) {
        WebSocketServer serverA = WebSocketServer.users.get(playerA.getId());
        WebSocketServer serverB = WebSocketServer.users.get(playerB.getId());
        WebSocketServer serverC = WebSocketServer.users.get(playerC.getId());

        if (serverA != null) serverA.sendMessage(message);
        if (serverB != null) serverB.sendMessage(message);
        if (serverC != null) serverC.sendMessage(message);
    }

    private void updateUserRating(Player player, Integer rating) {
        User user = WebSocketServer.userMapper.selectById(player.getId());
        user.setRating(rating);
        WebSocketServer.userMapper.updateById(user);
    }

    private void saveToDatabase() {
        Integer ratingA = WebSocketServer.userMapper.selectById(playerA.getId()).getRating();
        Integer ratingB = WebSocketServer.userMapper.selectById(playerB.getId()).getRating();
        Integer ratingC = WebSocketServer.userMapper.selectById(playerC.getId()).getRating();

        if ("BC".equals(loser)) {  // A胜利
            ratingA += 5;
            ratingB -= 2;
            ratingC -= 2;
        } else if ("AC".equals(loser)) {  // B胜利
            ratingB += 5;
            ratingA -= 2;
            ratingC -= 2;
        } else if ("AB".equals(loser)) {  // C胜利
            ratingC += 5;
            ratingA -= 2;
            ratingB -= 2;
        } else if ("all".equals(loser)) {  // 平局
            ratingA -= 1;
            ratingB -= 1;
            ratingC -= 1;
        }

        updateUserRating(playerA, ratingA);
        updateUserRating(playerB, ratingB);
        updateUserRating(playerC, ratingC);
    }

    public void run() {
        System.out.println("游戏线程开始运行");
        
        // 初始化玩家生命值
        playerA.setHealth(100.0);
        playerA.setAlive(true);
        playerB.setHealth(100.0);
        playerB.setAlive(true);
        playerC.setHealth(100.0);
        playerC.setAlive(true);
        
        while (!gameOver) {
            try {
                Thread.sleep(50);  // 每50毫秒检查一次游戏状态
            } catch (InterruptedException e) {
                System.out.println("游戏线程被中断: " + e.getMessage());
                e.printStackTrace();
                break;
            }
        }
        
        System.out.println("游戏线程结束运行，最终状态: " + status + ", 败者: " + loser);
    }
}
